爬虫入门实战第二站 |
您所在的位置:网站首页 › python 文本加密 › 爬虫入门实战第二站 |
爬虫入门实战第二站-爬取网易云歌曲评论
简介
之前的工作:爬虫入门实战第一站——梨视频视频爬取 由于csdn中无法发布爬虫的内容,就在这里发布了。 这次的任务是获取网易云音乐下面的评论,涉及的知识比上次更多,包括Js逆向的知识。 使用的python包: execjs(运行Js文件,通过pip install PyExecJS安装) requests(发起请求) json(json数据转换)使用浏览器: Edge浏览器 步骤网易云音乐网站 1.找到一首歌曲刷新网页进行抓包,结果如下:
点击这些接口,然后点击预览,预览里面是接口的返回数据,我们看下是否有评论数据。
在搜索栏搜索评论信息,找到接口,这个比上面一个一个接口分析要快。但注意如果页面加密了就不行了。
(1)点击负载,可以看到接口的参数是进行了加密的,那我们需要找到它是如何进行加密的。
(6)找到数据后,分析它是如何进行加密的。
打开第(5)步找到的文件并打上断点,如图所示:
找到第4步的window.asrsea函数,通过在文件里面按下Ctrl+F键,然后进行搜索。
对于上述加密函数的实现,有两种方式: 使用js实现,通过该文件中的函数实现加密功能,遇到缺少的函数继续在该文件中查找。补齐后通过python的库函数调用js文件实现加密功能。 使用python实现,通过分析加密函数的逻辑,实现相同的功能。在说明下面内容之前,先看下d函数,有4个参数,再看下调用它的地方: window.asrsea(JSON.stringify(i0x), bsg8Y(["流泪", "强"]), bsg8Y(TH5M.md), bsg8Y(["爱心", "女孩", "惊恐", "大笑"]));我们看下它的每个参数的值,发现除了第一个参数,其他参数其实都是定值,通过运行这些函数,得到: e = '010001' f = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7' g = '0CoJUm6Qyw8W8jud'这对应d函数里面的参数,因此d函数只要传入一个字符串数据即可。 方法一这里我说下具体思路。
对于上面的加密函数整体框架,我们一个一个补齐里面缺少的函数。
我们发现c函数中的RSAKeyPair是需要补齐的,补齐方法如下:
由此得到加密后的数据,也就是d函数返回的数据。 然后封装成参数,即: post_data = {} post_data['params'] = ctx['encText'] post_data['encSecKey'] = ctx['encSecKey']最后发起请求: get_comment_url = 'https://music.163.com/weapi/comment/resource/comments/get?csrf_token=' response = requests.post(url=get_comment_url,data=post_data) 方法二先分析a函数,很明显它是要获得一个a位的随机字符串。 function a(a) { var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = ""; for (d = 0; a > d; d += 1) e = Math.random() * b.length, e = Math.floor(e), c += b.charAt(e); return c }然后分析b函数,它里面没有其他的随机数,都是用于加密的一些函数,因此给定固定的参数,它就是定值。 function b(a, b) { var c = CryptoJS.enc.Utf8.parse(b) , d = CryptoJS.enc.Utf8.parse("0102030405060708") , e = CryptoJS.enc.Utf8.parse(a) , f = CryptoJS.AES.encrypt(e, c, { iv: d, mode: CryptoJS.mode.CBC }); return f.toString() }对于c函数,也是一个加密的过程,没有随机因素。 function c(a, b, c) { var d, e; return setMaxDigits(131), d = new RSAKeyPair(b,"",c), e = encryptedString(d, a) }通过分析d函数,我们可以知道h.encText其实就是params参数,h.encSecKey其实就是encSecKey参数。对于h.encText,由于d对于不同的歌曲来说是不同的,所以我们需要手动实现加密过程。 然后对于 h.encSecKey,e和f都是定值,i我们在运行过程中获得,那么h.encSecKey就是一个定值,所以我们直接用运行过程中得到的i和h.encSecKey就行。 function d(d, e, f, g) { var h = {} , i = a(16); return h.encText = b(d, g), h.encText = b(h.encText, i), h.encSecKey = c(i, e, f), h }下面开始完成python代码。 首先,在运行过程中,我们得到i和h.encSecKey的值:
然后完成b函数的功能,这里使用了AES类,是Crypto里面的。 def enc_parmas(data,key): iv = "0102030405060708" data = to_16(data) aes = AES.new(key=key.encode("utf-8"),IV=iv.encode("utf-8"),mode=AES.MODE_CBC) bs = aes.encrypt(data.encode("utf-8")) return str(b64encode(bs),"utf-8")最后得到h.encText,也就是params参数。 def get_params(data): fisrt = enc_parmas(data,g) second = enc_parmas(fisrt,i) return second得到接口需要的参数后发起请求就可以得到评论数据了。需要注意传入的data参数是json字符串格式的。 6.获取评论数据通过发起请求后得到的内容为:
我们将其转换为json格式 response.encoding = 'utf-8' json_resp = response.json()然后获得json数据里面的评论数据: comments = json_resp['data']['comments'] for comment in comments: content = comment['content'] print(content)其他数据也可以获得,这需要自己分析json数据了。如评论数量: total_comment_num = json_resp['data']['totalCount'] 全部代码 使用Js文件Js文件目前没有提供,可以私聊我获取。 import json import execjs import requests get_comment_url = 'https://music.163.com/weapi/comment/resource/comments/get?csrf_token=' data = { "rid":"R_SO_4_472603422", "threadId":"R_SO_4_472603422", "pageNo":"1", "pageSize":"20", "cursor":"-1", "offset":"0", "orderType":"1", "csrf_token":"" } # 转换为json字符串 json_string = json.dumps(data) # 调用json文件 ctx = execjs.compile(open('encry.js', 'r', encoding='utf-8').read()).call('d', json_string) print(ctx) # 组成提交的数据 post_data = {} post_data['params'] = ctx['encText'] post_data['encSecKey'] = ctx['encSecKey'] # print(post_data) response = requests.post(url=get_comment_url,data=post_data) 只使用python from Crypto.Cipher import AES # pip install pycryptodome from base64 import b64encode import requests import json def get_encSecKey(): return "ByfLFqCAkOx5zSR+99lUdjEA9eCX9cDOLq/BrIAllXsAVuqJ64yyGo7DXxAN5UhksFOalcMawpjJhZP3wVfqmhBdCbxSSZvY4zblYWx8T34wkJVfRxzYnfmuYm3iRIqoAYcFjLzKvogEbOIwqYx7vWyob+neQC/TzS7uYK2VH7LhWTveYQ/4PXVk1lUyA3puYYTlvQ3TGfUThGzBRa0sw1poUwGsIUfI1UkhQpzCO1UZlev/3HkweKWwsRmLntYp6Mq2feSKOfuNu+tgJyLEeiwM9ZEkXrqJjepzwEeMzc8=" def to_16(data): pad = 16 - len(data) % 16 data += chr(pad) * pad return data def get_params(data): fisrt = enc_parmas(data,g) second = enc_parmas(fisrt,i) return second def enc_parmas(data,key): iv = "0102030405060708" data = to_16(data) aes = AES.new(key=key.encode("utf-8"),IV=iv.encode("utf-8"),mode=AES.MODE_CBC) bs = aes.encrypt(data.encode("utf-8")) return str(b64encode(bs),"utf-8") get_comment_url = 'https://music.163.com/weapi/comment/resource/comments/get?csrf_token=' data = { "rid": "R_SO_4_1325905146", "threadId": "R_SO_4_1325905146", "pageNo": "1", "pageSize": "2000", "cursor": "-1", "offset": "0", "orderType": "1", "csrf_token": "" } e = '010001' f = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7' g = '0CoJUm6Qyw8W8jud' i = 'ompBdaIcEweDSvm0' post_data = {} post_data['params'] = get_params(json.dumps(data)) post_data['encSecKey'] = get_encSecKey() resp = requests.post(url=get_comment_url,data=post_data) resp.encoding = 'utf-8' json_resp = resp.json() # print(json_resp) comments = json_resp['data']['comments'] for comment in comments: content = comment['content'] print(content) 小结与展望以上就是网易云音乐评论获取的全部内容了,其实该套加密程序在网易云音乐里面的其他功能也有使用,因此掌握了该方法其他功能也可以进行尝试,如网易云的搜索。 除此之外,data里面的rid的值R_SO_4_1325905146中1325905146其实就是歌词的id,因此可以改变它来获取不同的歌曲的评论,也可以通过改变pageSize来获取每页评论的数目。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |